package com.cold.legendary.bprocess.trigger.impl;

import com.alibaba.fastjson.JSON;
import com.cold.legendary.bprocess.common.constance.BErrorCodeEnum;
import com.cold.legendary.bprocess.common.exception.BProcessException;
import com.cold.legendary.bprocess.common.exception.BProcessInterruptException;
import com.cold.legendary.bprocess.context.ins.BArrowIns;
import com.cold.legendary.bprocess.context.ins.BPointIns;
import com.cold.legendary.bprocess.context.run.BContext;
import com.cold.legendary.bprocess.db.enums.PointRunStatusEnum;
import com.cold.legendary.bprocess.db.model.TbProcessRequest;
import com.cold.legendary.bprocess.definition.point.BPointService;
import com.cold.legendary.bprocess.trigger.AbstractBProcessTriggerService;
import com.cold.legendary.bprocess.trigger.BProcessTriggerService;
import com.cold.legendary.bprocess.trigger.enums.TriggerModeEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

/**
 * @author cold
 * @since 2023/3/10
 */
@Slf4j
@Service
public class ContinueBProcessTriggerService extends AbstractBProcessTriggerService {


    @Override
    public void triggerBPoint(BPointIns triggerBPointIns, BContext bContext) {
        try {
            //校验流程请求
            TbProcessRequest qryProcessRequest = processRequestCheckHelper.checkProcessRequest(bContext);

            //基础业务校验
            baseCheck(bContext, triggerBPointIns, qryProcessRequest);

            if (!PointRunStatusEnum.WAITING.getCode().equals(qryProcessRequest.getPointRunStatus())) {
                log.error("此节点非等待中状态!无法触发continue!bizId={}, merchantId={},processId={}",
                        bContext.getBizId(), bContext.getMerchantId(), bContext.getProcessId());
                throw new BProcessException(BErrorCodeEnum.SYS_CAN_NOT_CONTINUE_ERROR);
            }

            //执行当前节点继续执行业务逻辑
            log.info("<continue>-开始...triggerBPointId={}, bContext={}", triggerBPointIns.getPointId(), JSON.toJSONString(bContext));
            BPointService bPointService = triggerBPointIns.getBPointService();
            bPointService.execute(bContext);
            log.info("<continue>-结束...triggerBPointId={}, bContext={}", triggerBPointIns.getPointId(), JSON.toJSONString(bContext));

            //继续执行后,更新相关节点数据
            bProcessTransactionService.continuePoint(bContext, triggerBPointIns.getPointId(), triggerBPointIns);

            BArrowIns nextBArrowIns = triggerBPointIns.getNextBArrowIns();
            BPointIns nextBPointIns = nextBArrowIns.getNextBPointIns();

            BProcessTriggerService triggerService = factory.getBProcessTriggerService(TriggerModeEnum.EXECUTE);
            triggerService.triggerBPoint(nextBPointIns, bContext);
        } catch (BProcessInterruptException e) {
            log.info("捕捉到节点中断信号!执行中断逻辑! code={}, msg={}", e.getCode(), e.getMsg());
            if(StringUtils.isEmpty(bContext.getFailReason())) {
                bContext.setFailReason(e.getMsg());
            }
            bProcessService.interruptBProcess(bContext);
        } catch (Exception e) {
            log.error("触发等待节点发生异常!", e);
            throw e;
        }
    }

    @Override
    protected TriggerModeEnum getTriggerModeEnum() {
        return TriggerModeEnum.CONTINUE;
    }
}
